/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.mushroom.website.daoImpl;


import cz.muni.fi.pa165.mushroom.website.dao.MushroomDao;
import cz.muni.fi.pa165.mushroom.website.entities.Mushroom;
import cz.muni.fi.pa165.mushroom.website.entities.MushroomType;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.List;

/**
 * @author Pavol Donko
 */
@Repository
public class MushroomDaoImpl implements MushroomDao {


    @PersistenceContext
    private EntityManager em;


    public void createMushroom(Mushroom mushroom) {
        if (mushroom == null) {
            throw new IllegalArgumentException("Mushroom is null");
        }
        if (mushroom.getMushroomId() != null) {
            throw new IllegalArgumentException("Mushroom ID is already set");
        }
        if (mushroom.getName() == null) {
            throw new IllegalArgumentException("Mushroom has no name");
        }
        if (mushroom.getType() == null) {
            throw new IllegalArgumentException("Mushroom has no type");
        }        
        
        if ((mushroom.getGrowsFrom() < new Integer(1)) || (mushroom.getGrowsFrom() > new Integer(12))) {
            throw new IllegalArgumentException("Mushroom attribute 'GROW FROM' is beyond scope (1-12)");
        }
        if ((mushroom.getGrowsUntil() < new Integer(1)) || (mushroom.getGrowsUntil() > new Integer(12))) {
            throw new IllegalArgumentException("Mushroom attribute 'GROW UNTIL' is beyond scope (1-12)");
        }
        if (mushroom.getGrowsFrom() > mushroom.getGrowsUntil()) {
            throw new IllegalArgumentException("Mushroom attribute 'GROW FROM' is greater than attribute 'GROW UNTIL");
        }

        em.persist(mushroom);
    }

    public void updateMushroom(Mushroom mushroom) {
        if (mushroom == null) {
            throw new IllegalArgumentException("Mushroom is null");
        }
        if (mushroom.getMushroomId() == null) {
            throw new IllegalArgumentException("Mushroom has no ID");
        }
        if (mushroom.getName() == null) {
            throw new IllegalArgumentException("Mushroom has no name");
        }
        if (mushroom.getType() == null) {
            throw new IllegalArgumentException("Mushroom has no type");
        }
        if ((mushroom.getGrowsFrom() < new Integer(1)) || (mushroom.getGrowsFrom() > new Integer(12))) {
            throw new IllegalArgumentException("Mushroom attribute 'GROW FROM' is beyond scope (1-12)");
        }
        if ((mushroom.getGrowsUntil() < new Integer(1)) || (mushroom.getGrowsUntil() > new Integer(12))) {
            throw new IllegalArgumentException("Mushroom attribute 'GROW UNTIL' is beyond scope (1-12)");
        }
        if (mushroom.getGrowsFrom() > mushroom.getGrowsUntil()) {
            throw new IllegalArgumentException("Mushroom attribute 'GROW FROM' is greater than attribute 'GROW UNTIL");
        }

        em.merge(mushroom);
    }

    public void removeMushroom(Mushroom mushroom) {
        if (mushroom == null) {
            throw new IllegalArgumentException("Mushroom is null");
        }
        if (mushroom.getMushroomId() == null) {
            throw new IllegalArgumentException("Mushroom has no ID");
        }

        em.remove(em.contains(mushroom) ? mushroom : em.merge(mushroom)); 
    }

    public Mushroom findMushroom(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("Mushroom has no ID");
        }

        return em.find(Mushroom.class, id);
    }

    public List<Mushroom> listMushrooms() {
        TypedQuery<Mushroom> query = em.createQuery("SELECT m FROM Mushroom m", Mushroom.class);
        return query.getResultList();
    }

    public List<Mushroom> listMushroomsWithType(MushroomType type) {
        TypedQuery<Mushroom> query = em.createQuery("SELECT m FROM Mushroom m "
                + "WHERE m.type=?1", Mushroom.class).setParameter(1, type);
        return query.getResultList();
    }

    public List<Mushroom> listMushroomsWithName(String name) {
        TypedQuery<Mushroom> query = em.createQuery("SELECT m FROM Mushroom m WHERE m.name LIKE ?1",
                Mushroom.class).setParameter(1, "%" + name + "%");
        return query.getResultList();
    }

    public List<Mushroom> checkAvailability(Integer month) {
        TypedQuery<Mushroom> query = em.createQuery("SELECT m FROM Mushroom m "
                + "WHERE m.growsFrom<=?1 AND m.growsUntil>=?2", Mushroom.class).
                setParameter(1, month).setParameter(2, month);
        return query.getResultList();
    }

}
